package com.pg.auth.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pg.auth.model.dto.sysroleuser.SysRoleUserConvertor;
import com.pg.auth.model.dto.sysroleuser.SysRoleUserDTO;
import com.pg.auth.model.dto.sysroleuser.SysRoleUserReq;
import com.pg.auth.model.dto.sysroleuser.SysRoleUserVO;
import com.pg.auth.model.entity.SysRoleMenu;
import com.pg.auth.model.entity.SysRoleUser;
import com.pg.auth.model.mapper.SysRoleUserMapper;
import com.pg.auth.service.SysRoleUserService;
import com.pg.base.component.PageVO;
import com.pg.base.component.Pager;
import com.pg.base.enums.DeleteEnum;
import com.pg.base.vo.LoginVO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/***
 * SysRoleUserServiceImpl
 * @author : huhuaping
 * @Date : 2024-06-06 20:59:34
 */
@Slf4j
@Service
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class SysRoleUserServiceImpl implements SysRoleUserService {

    private final SysRoleUserMapper sysRoleUserMapper;

    @Override
    public PageVO<SysRoleUserVO> page(Pager<SysRoleUserReq, SysRoleUserVO> pageReq){

        QueryWrapper<SysRoleUser> queryWrapper = baseQueryWrapper(pageReq.getParam());

        PageVO<SysRoleUserVO> result = sysRoleUserMapper.selectPage(pageReq.getPageVO(), queryWrapper);
        return result;
    }

    @Override
    public List<SysRoleUserVO> list(SysRoleUserReq sysRoleUserReq){

        QueryWrapper<SysRoleUser> queryWrapper = baseQueryWrapper(sysRoleUserReq);

        List<SysRoleUser> sysRoleUserList = sysRoleUserMapper.selectList(queryWrapper);

        return SysRoleUserConvertor.INSTANCE.listDbToVO(sysRoleUserList);

    }

    @Override
    public SysRoleUserVO getById(Long roleUserId) {
        SysRoleUser sysRoleUser = sysRoleUserMapper.selectById(roleUserId);
        return SysRoleUserConvertor.INSTANCE.dbToVO(sysRoleUser);
    }

    @Override
    public Long add(SysRoleUserDTO sysRoleUserDTO,LoginVO userVo) {
        SysRoleUser sysRoleUserAdd = SysRoleUserConvertor.INSTANCE.dtoToDB(sysRoleUserDTO);
        sysRoleUserMapper.insert(sysRoleUserAdd);
        return sysRoleUserAdd.getRoleUserId();
    }



    @Override
    public Integer updateById(SysRoleUserDTO sysRoleUserDTO,LoginVO userVo) {
        SysRoleUser sysRoleUserAdd = SysRoleUserConvertor.INSTANCE.dtoToDB(sysRoleUserDTO);
        int count = sysRoleUserMapper.updateById(sysRoleUserAdd);
        return count;
    }

    @Override
    public int deleteById(Long roleUserId) {
        SysRoleUser sysRoleUser = sysRoleUserMapper.selectById(roleUserId);

        // 封装对象
        SysRoleUser sysRoleUserDelete = new SysRoleUser();

        sysRoleUserDelete.setRoleUserId(roleUserId);
        sysRoleUserDelete.setDeleteStatus(DeleteEnum.DELETE.getValue());

        return sysRoleUserMapper.updateById(sysRoleUserDelete);

    }

    @Override
    public int save(Long userId, List<Long> roleIds, LoginVO loginVO) {

        roleIds = Optional.ofNullable(roleIds).orElse(new ArrayList<>());

        // 查询数据库中的关系
        QueryWrapper<SysRoleUser> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SysRoleUser> lambda =  queryWrapper.lambda();
        lambda.eq(SysRoleUser::getDeleteStatus,DeleteEnum.NORMAL.getValue());
        lambda.in(SysRoleUser::getRoleId, roleIds);
        List<SysRoleUser> sysRoleUsers = sysRoleUserMapper.selectList(queryWrapper);

        List<Long> dbRoleList = sysRoleUsers.stream().map(SysRoleUser::getRoleId).collect(Collectors.toList());

        List<Long> addList = roleIds.stream().filter(item -> !dbRoleList.contains(item)).collect(Collectors.toList());
        List<Long> finalRoleIdList = roleIds;
        List<Long> delList = dbRoleList.stream().filter(item -> !finalRoleIdList.contains(item)).collect(Collectors.toList());

        // 新增关系
        addList.forEach(item -> {;
            if (item !=null){
                SysRoleUser SysRoleUserAdd = new SysRoleUser();
                SysRoleUserAdd.setRoleId(item);
                SysRoleUserAdd.setUserId(userId);

                SysRoleUserAdd.setCreateTime(new Date());
                SysRoleUserAdd.setDeleteStatus(DeleteEnum.NORMAL.getValue());

                if( ObjectUtil.isNotEmpty(loginVO)) {
                    SysRoleUserAdd.setCreateUser(loginVO.getUserId());
                    SysRoleUserAdd.setCreateUserName(loginVO.getLoginName());
                }
                sysRoleUserMapper.insert(SysRoleUserAdd);
            }
        });

        // 删除关系
        if (!delList.isEmpty()) {

            QueryWrapper<SysRoleUser> delWrapper = new QueryWrapper<>();
            LambdaQueryWrapper<SysRoleUser> lambda1 =  delWrapper.lambda();
            lambda1.in(SysRoleUser::getRoleId,delList)
                    .eq(SysRoleUser::getUserId,userId);

            sysRoleUserMapper.delete(delWrapper);
        }
        log.info("save role user relation userId [{}] roleIds [{}],del [{}] op userId[{}]",userId, JSON.toJSONString(roleIds),JSON.toJSONString(delList),JSON.toJSONString(loginVO));

        return roleIds.size();
    }


    private QueryWrapper<SysRoleUser> baseQueryWrapper(SysRoleUserReq sysRoleUser) {
        QueryWrapper<SysRoleUser> queryWrapper = new QueryWrapper<>();
        LambdaQueryWrapper<SysRoleUser> lambda =  queryWrapper.lambda();
        lambda.eq(SysRoleUser::getDeleteStatus,DeleteEnum.NORMAL.getValue());
            lambda.orderByDesc(SysRoleUser::getRoleUserId);
        if (ObjectUtil.isNotEmpty(sysRoleUser.getRoleUserId())) {
            lambda.eq(SysRoleUser::getRoleUserId, sysRoleUser.getRoleUserId());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getRoleId())) {
            lambda.eq(SysRoleUser::getRoleId, sysRoleUser.getRoleId());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getUserId())) {
            lambda.eq(SysRoleUser::getUserId, sysRoleUser.getUserId());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getCreateUser())) {
            lambda.eq(SysRoleUser::getCreateUser, sysRoleUser.getCreateUser());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getCreateUserName())) {
            lambda.eq(SysRoleUser::getCreateUserName, sysRoleUser.getCreateUserName());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getCreateTime())) {
            lambda.eq(SysRoleUser::getCreateTime, sysRoleUser.getCreateTime());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getUpdateUser())) {
            lambda.eq(SysRoleUser::getUpdateUser, sysRoleUser.getUpdateUser());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getUpdateUserName())) {
            lambda.eq(SysRoleUser::getUpdateUserName, sysRoleUser.getUpdateUserName());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getUpdateTime())) {
            lambda.eq(SysRoleUser::getUpdateTime, sysRoleUser.getUpdateTime());
        }
        if (ObjectUtil.isNotEmpty(sysRoleUser.getDeleteStatus())) {
            lambda.eq(SysRoleUser::getDeleteStatus, sysRoleUser.getDeleteStatus());
        }
        return queryWrapper;
    }

}
